<template>
  <div class="root_app">
    <ant-v ref="graphDom"/>
  </div>
</template>
<script setup>
import AntV from '@/components/graph/index.vue'
import {onMounted, ref} from "vue";
import graphData from '@/assets/data3'
import graphData1 from '@/assets/data4'
import graphData2 from '@/assets/data5'
import emitter from "@/utils/emitter.js";
import {graphExample} from "@/components/graph/config/main.js";

let graphDom = ref()

// 初始化图谱
async function readyGraph(configGraphData) {
  if (configGraphData.data.nodes.length >= 30) {
    configGraphData.optionsConfig.defaultAutoFit = 'view'
  }
  graphDom.value.initGraph(configGraphData);
}

onMounted(() => {
  // // 接收消息
  receiveMessage()
  // // 准备数据
  let startNode = graphData2.nodes[0]
  let a1 = upwardFindData(startNode)
  let a2 = downwardFindData(startNode, 1)
  let cc = {
    nodes: [...a1.nodes, ...a2.nodes],
    edges: [...a1.edges, ...a2.edges]
  }
  const data = {
    data: cc,
    optionsConfig: {
      isNewData: true,
      bindNodeClick: true,
      layout: "compactBox",
      padding: [80, 80, 80, 80],
      animation: false,
      defaultNodeSize: 40,
      defaultLabelSize: 14,
      defaultNodeFill: null,
      defaultAutoFit: 'center',
    },
    configuration: {
      edgeLabel: null,
      edgeId: null,
      nodeId: "id",
      nodeLabel: "label",
      source: "source",
      target: "target",
      nodeType: 'nodeType'
    }
  }
  // // 准备初始化图谱
  readyGraph(data)
  //向父元素发送消息
  // setTimeout(() => {
  //   const params = {
  //     signal: 'iframeFinish',
  //     data: {status: 200, msg: "iframe已经加载完成"}
  //   }
  //   // 向父页面发送消息
  //   window.parent.postMessage(params, '*');
  // })
})


// 接收消息
function receiveMessage() {
  //接收父组件的消息
  window.addEventListener('message', function (event) {
    // 处理接收到的消息
    if (event.data.signal && event.data.signal === 'graphData') {
      // 医学院数据
      if (event.data.data === 1) {
        const data = {
          data: graphData1,
          optionsConfig: {
            isNewData: true,
            bindNodeClick: true,
            layout: "d3Force",
            padding: [80, 80, 80, 80],
            animation: false,
            defaultNodeSize: 40,
            defaultLabelSize: 14,
            defaultNodeFill: null,
            defaultAutoFit: 'center',
          },
          configuration: {
            edgeLabel: null,
            edgeId: null,
            nodeId: "id",
            nodeLabel: "name",
            source: "Source",
            target: "Target",
            nodeType: 'type'
          }
        }
        readyGraph(data)
      } else {
        // 地理数据
        let startNode = graphData2.nodes[0]
        let a1 = upwardFindData(startNode)
        let a2 = downwardFindData(startNode, 1)
        let cc = {
          nodes: [...a1.nodes, ...a2.nodes],
          edges: [...a1.edges, ...a2.edges]
        }
        const data = {
          data: cc,
          optionsConfig: {
            isNewData: true,
            bindNodeClick: true,
            layout: "compactBox",
            padding: [80, 80, 80, 80],
            animation: false,
            defaultNodeSize: 40,
            defaultLabelSize: 14,
            defaultNodeFill: null,
            defaultAutoFit: 'center',
          },
          configuration: {
            edgeLabel: 'label',
            edgeId: null,
            nodeId: "id",
            nodeLabel: "label",
            source: "source",
            target: "target",
            nodeType: 'nodeType'
          }
        }
        // 初始化图谱
        readyGraph(data)
      }
    }
  });
  emitter.on('refreshData', (params) => {
    let findCountLevel = params.data.id === '7' ? 10 : 1
    let a1 = upwardFindData(params.data)
    let a2 = downwardFindData(params.data, findCountLevel)
    let cc = {
      nodes: [...a1.nodes, ...a2.nodes],
      edges: [...a1.edges, ...a2.edges]
    }
    const data = {
      data: cc,
      optionsConfig: {
        isNewData: true,
        bindNodeClick: true,
        layout: "compactBox",
        padding: [80, 80, 80, 80],
        animation: false,
        defaultNodeSize: 40,
        defaultLabelSize: 14,
        defaultNodeFill: null,
        defaultAutoFit: 'center',
      },
      configuration: {
        edgeLabel: 'label',
        edgeId: null,
        nodeId: "id",
        nodeLabel: "label",
        source: "source",
        target: "target",
        nodeType: 'nodeType'
      }
    }
    readyGraph(data)
    if (params.data.id === '7') {
      setTimeout(() => {
        graphExample.updateNodeData([{
          id: params.data.id,
          data: {
            type: "breathing-circle",
            halo: true
          },
        }])
        graphExample.draw()
      }, 1000)
    }
  })
}

// 向上查找数据
function upwardFindData(startNodes) {
  let {nodes, edges} = graphData2
  let graphData12 = {
    nodes: [],
    edges: []
  }

  // 递归查找
  function recursionFind(startNodes) {
    let prevEdge = edges.find(v => v.target === startNodes.id)
    if (prevEdge) {
      let prevNode = nodes.find(v => v.id === prevEdge.source)
      graphData12.nodes.push(prevNode)
      graphData12.edges.push(prevEdge)
      recursionFind(prevNode)
    }
  }

  recursionFind(startNodes)
  return graphData12
}

// 向下查找数据
function downwardFindData(startNodes, findCountLevel) {
  let {nodes, edges} = graphData2
  let graphData12 = {
    nodes: [startNodes],
    edges: []
  }
  let countLevel = 0

  function recursionFind(startNodes, countLevel) {
    if (countLevel === findCountLevel) {
      return
    }
    countLevel++
    let nextEdge = edges.filter(v => v.source === startNodes.id)
    if (nextEdge.length) {
      nextEdge.forEach(v => {
        let nextNode = nodes.find(item => v.target === item.id)
        graphData12.nodes.push(nextNode)
        graphData12.edges.push(v)
        recursionFind(nextNode, countLevel)
      })
    }
  }

  recursionFind(startNodes, countLevel)
  return graphData12
}

</script>
<style scoped>
.root_app {
  width: 100%;
  height: 100%;
  padding: 20px;
  background: rgba(255, 255, 255, 1);
  backdrop-filter: blur(10px);
  box-sizing: border-box;
  position: relative;
}
</style>
